package io.youngledo.usb.task;

import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import lombok.Getter;
import lombok.Setter;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

/**
 * 任务进度对话框 - 显示单个或多个任务的进度
 */
public class TaskProgressDialog {

    private Stage dialogStage;
    private TaskManager taskManager;
    private VBox tasksContainer;

    private boolean showingMultipleTasks = false;
    private boolean isMonitoringAllTasks = false;

    /**
     * -- SETTER --
     * 设置任务数量变化回调
     */
    // 任务数量变化回调
    @Setter
    private Consumer<Integer> onTaskCountChanged;

    public TaskProgressDialog(Stage parent) {
        this.taskManager = TaskManager.getInstance();
        createDialog(parent);
    }

    /**
     * 显示所有活动任务
     */
    public void showAllActiveTasks() {
        List<StorageTask> activeTasks = taskManager.getActiveTasks();
        if (activeTasks.isEmpty()) {
            // 即使没有活动任务，也显示空的多任务界面并设置监听器
            showingMultipleTasks = true;
            Platform.runLater(() -> {
                dialogStage.setTitle("任务进度 - 0 个任务");
                tasksContainer.getChildren().clear();

                // 状态信息已通过对话框标题显示，无需额外的状态标签

                // 设置监听器以便新任务添加时自动显示
                setupTaskAddedListener();
            });
            showDialog();
            return;
        }

        showingMultipleTasks = true;
        setupMultipleTasksView(activeTasks);
        showDialog();
    }

    private void createDialog(Stage parent) {
        dialogStage = new Stage();
        dialogStage.initOwner(parent);
        dialogStage.initModality(Modality.NONE); // 允许用户继续操作主窗口
        dialogStage.initStyle(StageStyle.UTILITY);
        dialogStage.setTitle("任务进度");
        dialogStage.setResizable(true);

        // 创建主布局
        BorderPane root = createMainLayout();
        Scene scene = new Scene(root, 500, 300);

        // 加载扁平化CSS样式
        String css = getClass().getResource("/styles/application.css").toExternalForm();
        scene.getStylesheets().add(css);

        dialogStage.setScene(scene);

        // 设置关闭事件
        dialogStage.setOnCloseRequest(event -> {
            // 清理任务监听器
            clearTaskListener();
            // 清理完成时间映射
            taskCompletionTimes.clear();
            // 隐藏而不是关闭，允许重新显示
            dialogStage.hide();
        });
    }

    private BorderPane createMainLayout() {
        BorderPane root = new BorderPane();

        // 中央任务列表
        ScrollPane scrollPane = new ScrollPane();
        tasksContainer = new VBox();
        tasksContainer.setSpacing(10);
        tasksContainer.setPadding(new Insets(10));
        scrollPane.setContent(tasksContainer);
        scrollPane.setFitToWidth(true);
        root.setCenter(scrollPane);

        // 移除底部按钮区域

        return root;
    }

    private void setupMultipleTasksView(List<StorageTask> tasks) {
        Platform.runLater(() -> {
            dialogStage.setTitle(String.format("任务进度 - %d 个任务", tasks.size()));
            tasksContainer.getChildren().clear();

            for (StorageTask task : tasks) {
                TaskProgressItem progressItem = new TaskProgressItem(task);
                progressItem.setOnRemoveRequest(this::removeTaskFromDialog);
                tasksContainer.getChildren().add(progressItem);
            }

            // 状态信息已通过对话框标题显示

            // 设置新任务监听
            setupTaskAddedListener();
        });
    }

    private void showDialog() {
        if (!dialogStage.isShowing()) {
            // 先设置初始位置的估计值，避免显示在屏幕中间
            setInitialPosition();
            dialogStage.show();
            // 显示后再精确定位
            Platform.runLater(this::positionDialogBottomRight);
        } else {
            dialogStage.toFront();
        }
    }

    /**
     * 设置对话框的初始位置估计值，避免显示在屏幕中间
     */
    private void setInitialPosition() {
        Stage parentStage = (Stage) dialogStage.getOwner();
        if (parentStage == null) return;

        double parentX = parentStage.getX();
        double parentY = parentStage.getY();
        double parentWidth = parentStage.getWidth();
        double parentHeight = parentStage.getHeight();

        // 使用估计的对话框尺寸
        double estimatedWidth = 500;
        double estimatedHeight = 300;
        double margin = 20;
        double scrollbarWidth = 20;
        double statusBarHeight = 30;

        // 计算估计位置
        double x = parentX + parentWidth - estimatedWidth - margin - scrollbarWidth;
        double y = parentY + parentHeight - estimatedHeight - margin - statusBarHeight;

        // 确保不超出父窗口边界
        x = Math.max(parentX + margin, x);
        y = Math.max(parentY + margin, y);

        dialogStage.setX(x);
        dialogStage.setY(y);
    }

    /**
     * 将对话框定位到应用程序窗口的右下角，避免遮挡状态栏和滚动条
     */
    private void positionDialogBottomRight() {
        // 获取父窗口（应用程序主窗口）的位置和尺寸
        Stage parentStage = (Stage) dialogStage.getOwner();
        if (parentStage == null) return;

        double parentX = parentStage.getX();
        double parentY = parentStage.getY();
        double parentWidth = parentStage.getWidth();
        double parentHeight = parentStage.getHeight();

        // 计算对话框位置，留出边距避免遮挡状态栏和滚动条
        double margin = 20; // 边距
        double scrollbarWidth = 20; // 滚动条宽度估计
        double statusBarHeight = 30; // 状态栏高度估计

        double dialogWidth = dialogStage.getWidth();
        double dialogHeight = dialogStage.getHeight();

        // 如果对话框尺寸还未确定，等待下次定位
        if (dialogWidth <= 0 || dialogHeight <= 0) {
            return;
        }

        // 计算在父窗口右下角的位置
        double x = parentX + parentWidth - dialogWidth - margin - scrollbarWidth;
        double y = parentY + parentHeight - dialogHeight - margin - statusBarHeight;

        // 确保对话框不会超出父窗口边界，至少保持在父窗口内
        x = Math.max(parentX + margin, x);
        y = Math.max(parentY + margin, y);

        dialogStage.setX(x);
        dialogStage.setY(y);
    }

    /**
     * 设置任务监听器
     */
    private void setupTaskAddedListener() {
        if (!isMonitoringAllTasks) {
            isMonitoringAllTasks = true;

            // 创建并保存监听器引用
            taskAddedListener = newTask -> {
                Platform.runLater(() -> {
                    if (dialogStage.isShowing()) {
                        // 检查该任务是否已经在显示列表中
                        boolean taskExists = tasksContainer.getChildren().stream()
                            .filter(node -> node instanceof TaskProgressItem)
                            .map(node -> (TaskProgressItem) node)
                            .anyMatch(item -> item.getTask().getTaskId().equals(newTask.getTaskId()));

                        if (!taskExists) {
                            // 添加新任务到显示列表
                            TaskProgressItem progressItem = new TaskProgressItem(newTask);
                            progressItem.setOnRemoveRequest(this::removeTaskFromDialog);
                            tasksContainer.getChildren().add(progressItem);

                            // 如果当前只有一个任务且不是多任务模式，切换到多任务模式
                            int taskCount = (int) tasksContainer.getChildren().stream()
                                .filter(node -> node instanceof TaskProgressItem)
                                .count();

                            boolean wasInSingleTaskMode = !showingMultipleTasks;

                            if (taskCount > 1 && !showingMultipleTasks) {
                                // 切换到多任务模式
                                showingMultipleTasks = true;
                                // 状态信息已通过对话框标题显示
                            }

                            // 更新标题
                            updateDialogTitle();
                        }
                    }
                });
            };

            // 监听任务添加
            taskManager.addOnTaskAddedListener(taskAddedListener);

            // 启动定期任务检查器，移除已完成的任务
            startTaskCleanupTimer();
        }
    }

    /**
     * 更新对话框标题
     */
    private void updateDialogTitle() {
        int taskCount = (int) tasksContainer.getChildren().stream()
            .filter(node -> node instanceof TaskProgressItem)
            .count();
        dialogStage.setTitle(String.format("任务进度 - %d 个任务", taskCount));

        // 通知主界面更新任务管理按钮
        if (onTaskCountChanged != null) {
            onTaskCountChanged.accept(taskCount);
        }
    }

    /**
     * 启动任务清理定时器
     */
    private void startTaskCleanupTimer() {
        javafx.concurrent.Task<Void> cleanupTask = new javafx.concurrent.Task<Void>() {
            @Override
            protected Void call() throws Exception {
                while (!isCancelled() && dialogStage.isShowing()) {
                    Platform.runLater(() -> {
                        if (dialogStage.isShowing()) {
                            cleanupCompletedTasks();
                        }
                    });
                    Thread.sleep(2000); // 每2秒检查一次
                }
                return null;
            }
        };

        // 使用TaskManager的线程池提交清理任务
        taskManager.submitTask(cleanupTask);
    }

    // 用于记录任务完成时间的映射
    private final Map<String, Long> taskCompletionTimes = new ConcurrentHashMap<>();

    /**
     * 清理已完成的任务
     */
    private void cleanupCompletedTasks() {
        // 获取所有已完成的任务项目
        List<TaskProgressItem> completedItems = tasksContainer.getChildren().stream()
            .filter(node -> node instanceof TaskProgressItem)
            .map(node -> (TaskProgressItem) node)
            .filter(item -> item.getTask().getTaskStatus().isFinished())
            .toList();

        long currentTime = System.currentTimeMillis();

        // 记录新完成的任务并移除老的已完成任务
        for (TaskProgressItem item : completedItems) {
            StorageTask task = item.getTask();
            String taskId = task.getTaskId();

            // 如果是新完成的任务，记录完成时间
            if (!taskCompletionTimes.containsKey(taskId)) {
                taskCompletionTimes.put(taskId, currentTime);
            }

            // 根据任务状态决定是否清理
            Long completionTime = taskCompletionTimes.get(taskId);
            if (completionTime != null) {
                TaskStatus status = task.getTaskStatus();

                // 根据任务状态决定清理策略
                if (status == TaskStatus.FAILED) {
                    // 失败任务不自动清理，一直保留
                    continue;
                } else if (status == TaskStatus.CANCELLED) {
                    // 取消任务显示5秒后清理
                    if ((currentTime - completionTime) > 5000) {
                        tasksContainer.getChildren().remove(item);
                        taskCompletionTimes.remove(taskId);
                    }
                } else if (status == TaskStatus.COMPLETED) {
                    // 成功完成的任务显示3秒后清理
                    if ((currentTime - completionTime) > 3000) {
                        tasksContainer.getChildren().remove(item);
                        taskCompletionTimes.remove(taskId);
                    }
                }
            }
        }

        // 更新标题
        updateDialogTitle();
    }

    // 保存监听器引用以便后续移除
    private Consumer<StorageTask> taskAddedListener;

    /**
     * 清理任务监听器
     */
    private void clearTaskListener() {
        if (isMonitoringAllTasks) {
            isMonitoringAllTasks = false;
            if (taskAddedListener != null) {
                taskManager.removeOnTaskAddedListener(taskAddedListener);
                taskAddedListener = null;
            }
        }
    }

    /**
     * 从对话框中移除指定的任务项
     */
    private void removeTaskFromDialog(TaskProgressItem item) {
        Platform.runLater(() -> {
            tasksContainer.getChildren().remove(item);
            taskCompletionTimes.remove(item.getTask().getTaskId());
            updateDialogTitle();
        });
    }

    /**
     * 单个任务进度显示组件
     */
    private static class TaskProgressItem extends VBox {
        /**
         * -- GETTER --
         *  获取任务对象
         */
        @Getter
        private final StorageTask task;
        private final Label titleLabel;
        private final HBox statusRow;
        private final Label statusLabel;
        private final Label speedEtaLabel;
        private final ProgressBar progressBar;
        private final HBox buttonBox;
        private Button pauseResumeButton;
        private Button cancelButton;
        @Setter
        private Consumer<TaskProgressItem> onRemoveRequest;

        public TaskProgressItem(StorageTask task) {
            this.task = task;
            getStyleClass().add("task-progress-item");

            // 标题
            titleLabel = new Label(task.getDescription());
            titleLabel.getStyleClass().add("task-progress-title");

            // 进度条
            progressBar = new ProgressBar();
            progressBar.setPrefWidth(Double.MAX_VALUE);
            progressBar.setPrefHeight(20);

            // 状态行（包含百分比和速度/ETA信息）
            statusRow = new HBox();
            statusRow.setSpacing(10);

            // 状态标签（百分比等）
            statusLabel = new Label();
            statusLabel.getStyleClass().add("task-progress-status");

            // 速度和ETA标签（右对齐）
            speedEtaLabel = new Label();
            speedEtaLabel.getStyleClass().add("task-progress-speed");

            Region spacer = new Region();
            HBox.setHgrow(spacer, Priority.ALWAYS);

            statusRow.getChildren().addAll(statusLabel, spacer, speedEtaLabel);

            // 操作按钮
            buttonBox = createButtonBox();

            getChildren().addAll(titleLabel, progressBar, statusRow, buttonBox);

            // 绑定进度数据
            bindProgressData();
        }

        private HBox createButtonBox() {
            HBox box = new HBox();
            box.setSpacing(8);

            // 初始化按钮
            pauseResumeButton = new Button("暂停");  // 设置默认文字
            cancelButton = new Button("取消");

            // 设置按钮事件
            pauseResumeButton.setOnAction(e -> {
                if (task == null || task.getTaskId() == null) return;
                TaskStatus status = task.getTaskStatus();
                if (status == TaskStatus.RUNNING) {
                    TaskManager.getInstance().pauseTask(task.getTaskId());
                } else if (status == TaskStatus.PAUSED) {
                    TaskManager.getInstance().resumeTask(task.getTaskId());
                }
                updateButtonStates();
            });

            cancelButton.setOnAction(e -> {
                if (task == null || task.getTaskId() == null) return;

                TaskStatus status = task.getTaskStatus();
                if (status == TaskStatus.FAILED) {
                    // 失败任务点击清除按钮时，通过回调请求移除
                    if (onRemoveRequest != null) {
                        onRemoveRequest.accept(this);
                    }
                } else {
                    // 其他状态执行取消操作
                    TaskManager.getInstance().cancelTask(task.getTaskId());
                    updateButtonStates();
                }
            });

            Region spacer = new Region();
            HBox.setHgrow(spacer, Priority.ALWAYS);

            box.getChildren().addAll(spacer, pauseResumeButton, cancelButton);

            // 初始化按钮状态
            updateButtonStates();

            return box;
        }

        private void updateButtonStates() {
            // 如果 buttonBox 还未初始化，跳过更新
            if (buttonBox == null) {
                return;
            }

            TaskStatus status = task.getTaskStatus();

            // 也检查JavaFX Task状态来确保同步
            boolean isJavaFXTaskFinished = task.getState() == javafx.concurrent.Worker.State.SUCCEEDED ||
                                         task.getState() == javafx.concurrent.Worker.State.FAILED ||
                                         task.getState() == javafx.concurrent.Worker.State.CANCELLED;

            // 默认显示按钮
            buttonBox.setVisible(true);

            switch (status) {
                case RUNNING -> {
                    pauseResumeButton.setText("暂停");
                    pauseResumeButton.setDisable(false);
                    cancelButton.setText("取消");
                    cancelButton.setDisable(false);
                }
                case PAUSED -> {
                    pauseResumeButton.setText("继续");
                    pauseResumeButton.setDisable(false);
                    cancelButton.setText("取消");
                    cancelButton.setDisable(false);
                }
                case PENDING -> {
                    pauseResumeButton.setText("等待中");
                    pauseResumeButton.setDisable(true);
                    cancelButton.setText("取消");
                    cancelButton.setDisable(false);
                }
                case COMPLETED -> {
                    // 隐藏已完成任务的按钮
                    buttonBox.setVisible(false);
                }
                case FAILED -> {
                    pauseResumeButton.setText("已失败");
                    pauseResumeButton.setDisable(true);
                    cancelButton.setText("清除");
                    cancelButton.setDisable(false);
                }
                case CANCELLED -> {
                    // 隐藏已取消任务的按钮
                    buttonBox.setVisible(false);
                }
            }

            // 如果JavaFX Task已完成但TaskStatus还没更新，也隐藏按钮（除非是失败状态）
            if (isJavaFXTaskFinished && status != TaskStatus.FAILED) {
                buttonBox.setVisible(false);
            }
        }

        private void bindProgressData() {
            ProgressTracker tracker = task.getProgressTracker();

            // 绑定进度条
            progressBar.progressProperty().bind(tracker.progressProperty());

            // 绑定状态文本
            statusLabel.textProperty().bind(tracker.statusProperty());

            // 绑定速度和ETA信息
            tracker.speedProperty().addListener((obs, oldVal, newVal) -> {
                Platform.runLater(() -> updateSpeedEtaLabel(tracker));
            });

            tracker.etaProperty().addListener((obs, oldVal, newVal) -> {
                Platform.runLater(() -> updateSpeedEtaLabel(tracker));
            });

            // 监听任务状态变化，更新按钮状态
            tracker.statusProperty().addListener((obs, oldVal, newVal) -> {
                Platform.runLater(this::updateButtonStates);
            });

            // 也监听任务的JavaFX Task状态变化
            task.stateProperty().addListener((obs, oldVal, newVal) -> {
                Platform.runLater(this::updateButtonStates);
            });

            // 监听进度变化，当进度达到100%时也更新按钮状态
            tracker.progressProperty().addListener((obs, oldVal, newVal) -> {
                if (newVal.doubleValue() >= 1.0) {
                    Platform.runLater(this::updateButtonStates);
                }
            });
        }

        private void updateSpeedEtaLabel(ProgressTracker tracker) {
            String speed = tracker.getSpeed();
            String eta = tracker.getEta();
            if (!speed.isEmpty() || !eta.isEmpty()) {
                speedEtaLabel.setText(String.format("%s | %s", speed, eta));
            } else {
                speedEtaLabel.setText("");
            }
        }

    }
}